package ru.cjay.loading {

import core.Facade;

import flash.display.Stage;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.ProgressEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;


public class ResourceLoader extends EventDispatcher {

    private static var _instance:ResourceLoader;
    private static var _allowInstantiation:Boolean = false;

    private var _queue:Array = [];
    private var _timer:Timer;

    private var loaderAnim:LoaderAnim;

    public static function getInstance():ResourceLoader {
        if (!_instance) {
            _allowInstantiation = true;
            _instance = new ResourceLoader();
            _allowInstantiation = false;
        }
        return _instance;
    }

    public function ResourceLoader():void {
        if (!_allowInstantiation) {
            throw new Error("Error: Instantiation failed: Use ResourceLoader.getInstance() instead of new.");
        }
        loaderAnim = new LoaderAnim();
        _timer = new Timer(200, 1);
        _timer.addEventListener(TimerEvent.TIMER, onTimer);
    }


    private function onSwfComplete(event:Event):void {
        var obj:SWFAssetLoader = event.target as SWFAssetLoader;
        obj.removeEventListener(Event.COMPLETE, onSwfComplete);

        var pos:int = _queue.indexOf(obj);
        if (pos != -1) {
            _queue.splice(pos, 1);
        }
        onTimer(null);
    }


    private function onComplete(event:Event):void {
        event.target.removeEventListener(Event.COMPLETE, onComplete);

        var pos:int = _queue.indexOf(event.target);
        if (pos != -1) {
            _queue.splice(pos, 1);
        }
        onTimer(null);
    }

    public function loadQueue(queue:Object):void {
        var item:Object;
        var name:String;
        var url:String;
        var il:Object;

        var wasEmpty:Boolean = isEmpty();

        var rm:ResourceManager = ResourceManager.getInstance();

        // loading icons for zones
        for each (item in queue) {
            name = "zone_icon_" + item["zone_id"];
            url = item["img"];
            if (!rm.hasResource(url)) {
                il = new AssetLoader();
                il.loadFile(url, name);
                il.addEventListener(Event.COMPLETE, onComplete);
                _queue.push(il);
            }
        }

        for each (item in queue.images) {
            name = item["name"];
            url = item["url"];
            if (!rm.hasResource(url)) {
                il = new AssetLoader();
                il.loadImage(url, name);
                il.addEventListener(Event.COMPLETE, onComplete);
                _queue.push(il);
            }

        }

        if (wasEmpty) {
            var stage:Stage = Facade.getInstance().stage;

            stage.addChild(loaderAnim);
            loaderAnim.x = Facade.WIDTH * 0.5;
            loaderAnim.y = Facade.HEIGHT * 0.5;
            loaderAnim.alpha = 0;
            stage.setChildIndex(loaderAnim, stage.numChildren - 1);

            Lerp.getInstance().to(loaderAnim, 0.5, {alpha:1,scaleX:1,scaleY:1});

        }
        _timer.start();
    }

    public function loadSWFQueueFromObject(queue:Object):void {
        var name:String;
        var url:String;
        var il:SWFAssetLoader;
        var wasEmpty:Boolean = isEmpty();
        var rm:ResourceManager = ResourceManager.getInstance();

        for each (item in queue) {
            var item:SWFAssetList;
            name = item.name;
            url = item.url;
            if (!rm.hasResource(url)) {
                il = new SWFAssetLoader();
                il.loadSWF(item);
                il.addEventListener(Event.COMPLETE, onSwfComplete);
                _queue.push(il);
            }
        }

        // Show loader animated icon if ... )))
        if (wasEmpty) {
            var stage:Stage = Facade.getInstance().stage;
            stage.addChild(loaderAnim);
            loaderAnim.x = Facade.WIDTH * 0.5;
            loaderAnim.y = Facade.HEIGHT * 0.5;
            loaderAnim.alpha = 0;
            stage.setChildIndex(loaderAnim, stage.numChildren - 1);
            Lerp.getInstance().to(loaderAnim, 0.5, {alpha:1,scaleX:1,scaleY:1});
        }
        _timer.start();
    }

    public function loadQueueFromObject(queue:Object):void {
        var item:String;
        var name:String;
        var url:String;
        var il:Object;

        var wasEmpty:Boolean = isEmpty();
        var rm:ResourceManager = ResourceManager.getInstance();


        for (item in queue) {
            name = item;
            url = queue[item];
            if (!rm.hasResource(url)) {
                il = new AssetLoader();
                il.loadFile(url, name);
                il.addEventListener(Event.COMPLETE, onComplete);
                _queue.push(il);
            }
        }

        if (wasEmpty) {
            var stage:Stage = Facade.getInstance().stage;

            stage.addChild(loaderAnim);
            loaderAnim.x = Facade.WIDTH * 0.5;
            loaderAnim.y = Facade.HEIGHT * 0.5;
            loaderAnim.alpha = 0;
            stage.setChildIndex(loaderAnim, stage.numChildren - 1);

            Lerp.getInstance().to(loaderAnim, 0.5, {alpha:1,scaleX:1,scaleY:1});

        }
        _timer.start();
    }

    private function onTimer(event:TimerEvent):void {
        var total:int = 0;
        var loaded:int = 0;

        if (_queue.length == 0) {
            dispatchEvent(new Event(Event.COMPLETE, false, true));
            Lerp.getInstance().to(loaderAnim, 2, {alpha:0,scaleX:0.5,scaleY:0.5,handler:function():void {
                        if (loaderAnim.parent) {
                            loaderAnim.parent.removeChild(loaderAnim);
                        }
                    }
                    });
            _timer.stop();

            return;
        }

        var item:Object;
        for each(item in _queue) {
            total += item.totalBytes;
            loaded += item.loadedBytes;
        }

        dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, true, loaded, total));
        _timer.start();

    }

    public function isEmpty():Boolean {
        if (_queue.length == 0) return true;
        return false;
    }
}
}
